/*
 * Copyright © OpenAtom Foundation.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package io.iec.edp.caf.databaseobject.api.service;


import io.iec.edp.caf.databaseobject.api.entity.*;
import io.iec.edp.caf.dimension.api.entity.DimensionEntity;
import org.springframework.web.bind.annotation.RequestBody;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.sql.SQLException;
import java.util.*;
import java.util.List;

/**
 * DBO运行时服务接口
 *
 * @author zhaoleitr
 */
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
public interface IDatabaseObjectRtService {

    /**
     * 获取默认DBO实体列表
     *
     * @return DBO实体列表
     */
    @GET
    List<AbstractDatabaseObject> getDatabaseObjectList();

    /**
     * 获取未序列化content的数据库对象
     *
     * @return DBO实体列表
     */
    @GET
    @Path("/gspDatabaseObject/list")
    List<GspDatabaseObject> getGspDatabaseObjectList();

    /**
     * 获取默认DBO实体列表
     *
     * @param su  服务单元
     * @return DBO实体列表
     */
    //List<AbstractDatabaseObject> getDatabaseObjectList(String su);

    /**
     * 根据ID获取数据库对象表详细信息
     *
     * @param dboId 数据库对象ID
     * @return 数据库对象实体
     * 返回的数据库对象实体是基类，需要转成具体的类型，表转成DatabaseObjectTable，视图、函数、存储过程转成DatabaseObjectSPVF
     */
    @GET
    @Path(value = "/{dboId}")
    AbstractDatabaseObject getDatabaseObject(@PathParam("dboId") String dboId);

    /**
     * 清空全部mapping缓存
     */
    @POST
    @Path("/cache/clear/mapping")
    void clearDatabaseObjectMappingContent();

    /**
     * 根据dboIds清空缓存
     *
     * @param ids 数据库对象ID列表
     */
    @POST
    @Path("/cache/clear/mapping/ids")
    void clearDatabaseObjectMappingContentByIds(@RequestBody String ids);

    /**
     * 根据ID获取数据库对象表详细信息
     *
     * @param dboId 数据库对象Id
     * @param su  服务单元
     * @return 数据库对象实体
     */
    AbstractDatabaseObject getDatabaseObject(String dboId, String su);

    /**
     * 清空全部缓存
     */
    @POST
    @Path("/cache/clear")
    void clearDatabaseObjectContent();

    /**
     * 根据dboIds清空缓存
     *
     * @param ids 数据库对象ID列表
     */
    @POST
    @Path("/cache/clear/ids")
    void clearDatabaseObjectContentByIds(@RequestBody String ids);

    /**
     * 根据id清理缓存
     *
     * @param id 缓存id
     */
    void clearDatabaseObjectContentById(String id);

    /**
     * 添加DBO缓存
     *
     * @param databaseObject DBO对象
     */
    void addDatabaseObjectContent(AbstractDatabaseObject databaseObject);

    /**
     * 保存数据库对象表
     *
     * @param databaseObject 数据库对象
     */
    void saveDatabaseObject(AbstractDatabaseObject databaseObject);

    /**
     * 是否存在数据库对象
     *
     * @param dboId 数据库对象ID
     * @return 是否存在数据库对象，存在，返回true，否则返回false
     */
    boolean isExistDatabaseObject(String dboId);

    /**
     * 获取多语的数据库对象
     *
     * @return 数据库对象表列表
     */
    List<DatabaseObjectTable> getI18nObjectTables();

    /**
     * 根据数据库对象编号获取数据库对象
     *
     * @param dboCode 数据库对象编号
     * @return 数据库对象列表
     */
    AbstractDatabaseObject getDatabaseObjectByCode(String dboCode);

    /**
     * 根据数据库对象编号获取数据库对象
     *
     * @param dboCode 数据库对象编号
     * @param su  服务单元
     * @return 数据库对象列表
     */
    AbstractDatabaseObject getDatabaseObjectByCode(String dboCode, String su);

    /**
     * 根据数据库对象ID获取数据库对象编号
     *
     * @param dboId 数据库对象ID
     * @return 数据库对象编号
     */
    String getDatabaseObjectCodeById(String dboId);

    /**
     * 根据维度值获取表名
     *
     * @param dboId         数据库对象ID
     * @param dimensionInfo 维度信息
     * @return 表名
     */
    String getTableNameWithDimensionValue(String dboId, Map<String, String> dimensionInfo) throws RuntimeException;

    /**
     * 根据多个维护获取dbo的多个表名（例如多年度）
     *
     * @param dboId         数据库对象ID
     * @param dimensionInfo 多个维度信息
     * @return 一组表名
     */
    List<String> getTableNamesWithDimensionValues(String dboId, Map<String, List<String>> dimensionInfo);

    /**
     * 根据维度值获取表名
     *
     * @param dboCodes      数据库对象ID列表
     * @param dimensionInfo 维度信息
     * @return 表名
     */
    List<String> getTableNamesWithDimensionValue(List<String> dboCodes, Map<String, String> dimensionInfo);


    /**
     * 根据规则获取数据库对象表
     *
     * @param ruleCode 规则编号
     * @return 数据库对象列表
     */
    List<AbstractDatabaseObject> getDatabaseObjectByRule(String ruleCode);

    /**
     * 根据Dbo编号获取物理表列集合
     *
     * @param dboCode dbo编号
     * @return 物理表列集合
     */
    List<String> getTableColumnNamesByCode(String dboCode);


    /**
     * 根据Dbo编号获取物理表列集合
     *
     * @param dboCodes dbo编号列表
     * @return 编号和列集合的map
     */
    Map<String, List<String>> getTableColumnNamesByCode(List<String> dboCodes);

    /**
     * 根据传入的表ID和字段ID返回字段编号,如果启用多语，字段后根据当前语言拼上多语后缀
     *
     * @param tableId   表ID
     * @param columnIds 字段ID列表
     * @return 字段编号列表
     */
    List<String> getColumnCodeWithI18n(String tableId, List<String> columnIds);

    /**
     * 根据传入的表ID和字段ID返回字段编号,如果启用多语，会返回所有的多语字段
     *
     * @param tableId   表ID
     * @param columnIds 字段ID列表
     * @return 字段编号列表
     */
    Map<String,List<String>> getAllColumnCodeWithI18n(String tableId, List<String> columnIds);

    /**
     * 根据业务对象字段关联属性获取数据库对象
     *
     * @param businessObjectId 业务对象ID
     * @return 数据库对象列表
     */
    List<AbstractDatabaseObject> getDatabaseObjectByBOID(String businessObjectId);

    /**
     * 删除数据库对象
     *
     * @param dboId 数据库对象ID
     */
    void deleteDatabaseObject(String dboId);

    /**
     * 根据数据库对象ID获取维度实体
     *
     * @param dboId dboId
     * @return 维度实体
     */
    List<DimensionEntity> getDimensionListByDboId(String dboId);

    /**
     * 根据表名列表判断表是否存在
     *
     * @param tableNames 表名列表
     * @return 表和是否存在的map
     */
    Map<String, Boolean> isTablesExist(List<String> tableNames);

    /**
     * 根据dboId创建临时表
     *
     * @param dboId Id
     * @return 临时表上下文
     */
    TempTableContext creatTempTables(String dboId);

    /**
     * 临时表删除
     *
     * @param context 临时表上下文
     * @param dboId   Id
     */
    void dropTempTable(TempTableContext context, String dboId);
}
